#![allow(overflowing_literals)]

fn main() {
    let decimal = 65.4321_f32;

    // Error! No implicit conversion
    // let integer:u8 = decimal;
    // FIXME ^ comment out this line

    // explicit conversion
    let integer = decimal as u8;
    let character = integer as u8;

    // Error! There are limitations in conversion rules.
    // a float cannot be directly converted to a char
    // let character = decimal as char;
    // replace with the following line:
    // let character = decimal as u8 as char;

    println!("Casting: {} -> {} -> {}", decimal, integer, character);

    println!("1000 as a u16 is: {}", 1000 as u16);

    println!("1000 as a u8 is : {}", 1000 as u8);

    println!("-1 as a u8 is: {}", -1i8 as u8);

    println!("128 as a i16 is: {}", 128 as i16);

    println!("128 as a i8 is: {}", 128 as i8);

    println!("1000 as a u8 is: {}", 1000 as u8);
    println!("232 as a i8 is:{}", 232 as i8);

    // Since Rust 1.45, the `as` keyword performs a *saturating cast*
    // when casting from float to int. If the floating point value exceeds
    // the upper bound or is less than the lower bound, the returned value
    // will be equal to the bound crossed.

    // this is different from C
    // 300.0 as u8 is 255
    println!("300.0 as u8 is: {}", 300.0 as u8);

    // -100.0 as u8 is 0
    println!("-100.0 as u8 is: {}", -100.0 as u8);

    // nan as u8 is 0
    println!("nan as u8 is : {}", f32::NAN as u8);

    // normal value
    println!("123.0 as u8 is : {}", 123.0 as u8);

    // this behavior incurs a small runtime cost and can be avoided
    // with unsafe methods, however the results might overflow and
    // return **unsound values**. use these methods wisely:
    unsafe {
        // 300.0 as u8 is 44
        println!("300.0 as u8 is : {}", 300.0f32.to_int_unchecked::<u8>());
        // -100.0 as u8 is 156
        println!("-100.0 as u8 is : {}", (-100.0_f32).to_int_unchecked::<u8>());
        // nan as u8 is 0
        println!("nan as u8 is :{}", f32::NAN.to_int_unchecked::<u8>());
    }
}